
    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>hashSet怎么保证数据不重复 - 学习卡片</title>
      <style>
        body { font-family: sans-serif; background-color: #f0f8ff; color: #333; display: flex; flex-direction: column; align-items: center; padding: 50px 20px; }
        .header h1 { font-size: 32px; }
        .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; width: 100%; max-width: 1200px; }
        .card-container { perspective: 1200px; cursor: pointer; height: 250px; }
        .card { width: 100%; height: 100%; position: relative; transform-style: preserve-3d; transition: transform 0.7s; border-radius: 16px; box-shadow: 0 4px 16px rgba(0,0,0,0.08); }
        .card-container.flipped .card { transform: rotateY(180deg); }
        .card-face { position: absolute; width: 100%; height: 100%; backface-visibility: hidden; display: flex; flex-direction: column; box-sizing: border-box; border-radius: 16px; background-color: #fff; padding: 24px; }
        .card-back { background-color: #f0fff4; transform: rotateY(180deg); justify-content: space-between; }
        .card-category { font-size: 14px; color: #0052d9; margin-bottom: 8px; font-weight: 500; }
        .card-question { font-size: 20px; font-weight: 500; flex-grow: 1; display: flex; align-items: center; justify-content: center; text-align: center; }
        .card-answer-wrapper { flex-grow: 1; overflow-y: auto; }
        .card-answer { font-size: 15px; line-height: 1.7; }
        .card-footer { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 16px; margin-top: 16px; }
        .card-source { font-size: 13px; color: #8a919f; border-top: 1px solid #f0f0f0; padding-top: 12px; margin-top: 12px; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>hashSet怎么保证数据不重复 - 学习卡片</h1>
      </div>
      <div class="grid-container">
        
    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">原理</div>
          <div class="card-question">HashSet 的底层实现依赖于哪种数据结构？它如何利用该结构来存储元素？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">原理</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">HashSet 内部依赖于 HashMap 来存储元素。HashSet 中的每一个元素都作为其内部 HashMap 的键（key），而 HashMap 的值（value）则是一个固定的、名为 PRESENT 的常量对象。这种设计利用了 HashMap 键的唯一性来保证 HashSet 中元素的唯一性。</div>
          </div>
          <div class="card-source">来源: HashSet原理</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">当向 HashSet 添加一个新元素时，为了保证数据不重复，它会如何协同使用 `hashCode()` 和 `equals()` 方法？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">当添加新元素时，HashSet 首先调用该元素的 `hashCode()` 方法计算哈希值，以确定其在内部哈希表中的存储位置（桶）。如果该位置为空，则直接存入。如果该位置已有其他元素，则会依次调用桶内已有元素的 `equals()` 方法与新元素进行比较。如果 `equals()` 返回 true，则认为元素重复，不予添加；反之，则将新元素添加到该桶中。</div>
          </div>
          <div class="card-source">来源: 检测重复元素的详细过程</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">技术</div>
          <div class="card-question">HashSet 的 `add`、`remove` 和 `contains` 操作的平均和最坏情况下的时间复杂度分别是多少？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">技术</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">对于添加(add)、删除(remove)和查询(contains)操作，HashSet 在平均情况下的时间复杂度为 O(1)。但在最坏情况下，即所有元素的哈希值都相同导致所有元素都落入同一个桶中，时间复杂度会退化到 O(n)。</div>
          </div>
          <div class="card-source">来源: HashSet 的时间复杂度</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">除了保证元素唯一性之外，HashSet 还有哪些主要的特性？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">HashSet 的主要特性包括：1. 无序存储，不保证元素的存储顺序与插入顺序一致；2. 提供了常数时间复杂度（O(1)）的基本操作性能；3. 允许存储一个 null 值。</div>
          </div>
          <div class="card-source">来源: HashSet 的基本功能和用途</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">理论</div>
          <div class="card-question">什么是哈希冲突？文档中提到了哪两种常见的解决哈希冲突的方法？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">理论</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">哈希冲突是指不同的关键码（Key）被哈希函数映射到哈希表中相同索引位置的情况。文档中提到的常见解决方法有两种：链地址法（Separate Chaining），即每个桶中存储一个链表来存放哈希值相同的元素；以及开放地址法（Open Addressing），即当冲突发生时，通过探测找到下一个空桶来存储元素。</div>
          </div>
          <div class="card-source">来源: 哈希表的工作原理</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">在 HashSet 的底层实现 HashMap 中，是如何通过哈希码定位数组索引的？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">HashMap 使用按位与操作来确定数组索引。具体的计算公式是 `index = (n - 1) & hash`，其中 `n` 是哈希表数组的长度，`hash` 是经过计算和扰动后的哈希码。这个操作能确保计算出的索引值总是在数组的有效范围内。</div>
          </div>
          <div class="card-source">来源: HashSet储存过程</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">原理</div>
          <div class="card-question">在向 HashSet 底层的 HashMap 添加元素时，为什么要对 key 的 `hashCode()` 进行一次扰动运算 `(h = key.hashCode()) ^ (h >>> 16)`？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">原理</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">对 `hashCode()` 进行扰动运算的目的是为了提高哈希的分布性，减少哈希冲突。通过将哈希码的高16位与低16位进行异或操作，使得高位的信息也能参与到最终索引的计算中，从而让元素更均匀地分布在哈希表中。</div>
          </div>
          <div class="card-source">来源: HashSet储存过程</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">机制</div>
          <div class="card-question">当 HashSet 底层的 HashMap 容量不足时，会发生什么？这个过程叫什么？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">机制</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">当 HashMap 的元素数量超过其容量与负载因子的乘积（即阈值 threshold）时，会进行扩容（Rehashing）操作。扩容会创建一个新的、更大的数组，并将所有已有的节点重新计算哈希码在新数组中的索引位置，然后将它们重新分布到新的数组中。</div>
          </div>
          <div class="card-source">来源: HashSet储存过程</div>
        </div>
      </div>
    </div>

    <div class="card-container" onclick="this.classList.toggle('flipped');">
      <div class="card">
        <div class="card-face card-front">
          <div class="card-category">特性</div>
          <div class="card-question">HashSet 支持哪些常见的集合操作？通过哪些方法可以实现？</div>
          <div class="card-footer">点击卡片查看答案</div>
        </div>
        <div class="card-face card-back">
          <div class="card-category">特性</div>
          <div class="card-answer-wrapper">
            <div class="card-answer">HashSet 支持标准的集合操作，如并集、交集和差集。这些操作可以通过 `addAll()` (并集)、`retainAll()` (交集) 和 `removeAll()` (差集) 等方法来实现。</div>
          </div>
          <div class="card-source">来源: HashSet 的基本功能和用途</div>
        </div>
      </div>
    </div>

      </div>
    </body>
    </html>
